#define DEBUG
#include <cstdio>
#include <cstring>

using namespace std;

const int maxsize=200000, maxs=100000;

void swap(int &a, int &b) {
  int t;
  t=a, a=b, b=t;
}

int *getMem(int *a, int i, int j, int n) {
  return a+j*(n+1)+i;
}

int getSquare(int *f, int x1, int y1, int x2, int y2, int n) {
  return *getMem(f, x2, y2, n)-*getMem(f, x1-1, y2, n)-*getMem(f, x2, y1-1, n)+*getMem(f, x1-1, y1-1, n);
}

void update(int x, int y, int t[][2]) {
  if (x>=t[0][0]) {
    swap(t[0][0], x);
    t[0][1] = y;
  }
  if (x>=t[1][0]) {
    swap(t[1][0], x);
    t[1][1] = y;
  }
}

int max(int a, int b) {
  return a>b ? a : b;
}

int getLongest(int n, int m, int *suf[], int i, int j, int w[]) {
  int len=0, maxr[2][2]={}, maxl[2][2]={};
  for (int k=1; k<=m; k++) {
    if (!getSquare(suf[k], i, 1, j, w[k], n)) {
      len += w[k];
    } else {
      int t;
      for (t=1; t<=w[k]; t++) {
	if (getSquare(suf[k], i, 1, j, t, n)) {
	  break;
	}
      }
      t--;
      update(t, k, maxr);

      for (t=w[k]; t>0; t--) {
	if (getSquare(suf[k], i, t, j, w[k], n)) {
	  break;
	}
      }
      t = w[k]-t;
      update(t, k, maxl);
    }
  }
	  
  if (maxl[0][1] && maxl[0][1]!=maxr[0][1]) {
    return maxl[0][0]+maxr[0][0]+len;
  } else {
    return max(maxl[0][0]+maxr[1][0], maxl[1][0]+maxr[0][0])+len;
  }
}

int main() {
  freopen("puzzle.in", "r", stdin);
  freopen("puzzle.out", "w", stdout);

  static int mem[2*maxsize+1], *suf[maxs+1], w[maxs+1];
  int t;
  scanf("%d", &t);
  suf[0] = mem;
  for (int ti=1; ti<=t; ti++) {

    memset(mem, 0, sizeof mem);

    int s, n, m=0;
    scanf("%d %d", &s, &n);
    for (int i=1; i<=s; i++) {
      scanf("%d", w+i);
      m += w[i];
      suf[i] = getMem(suf[i-1], n, w[i-1], n)+1;
      for (int j=1; j<=n; j++) {
	for (int k=1; k<=w[i]; k++) {
	  int t;
	  scanf("%1d", &t);
	  *getMem(suf[i], j, k, n) = *getMem(suf[i], j-1, k, n)+*getMem(suf[i], j, k-1, n)-*getMem(suf[i], j-1, k-1, n)+t;
	}
      }
    }

    int ans=0;
    if (n<m) {
      for (int i=1; i<=s; i++) {
	for (int j=1; j<=n; j++) {
	  for (int k=j; k<=n; k++) {
	    for (int p=1, q=1; p<=w[i]; p=q+1) {
	      for (; q<=w[i] && !getSquare(suf[i], j, p, k, q, n); q++);
	      ans = max(ans, (q-p)*(k-j+1));
	    }
	  }
	}
      }

      for (int i=1; i<=n; i++) {
	for (int j=i; j<=n; j++) {
	  ans = max(ans, getLongest(n, s, suf, i, j, w)*(j-i+1));
	}
      }
    } else {
      for (int i=1; i<=s; i++) {
	for (int j=1; j<=w[i]; j++) {
	  for (int k=j; k<=w[i]; k++) {
	    for (int p=1, q=1; p<=n; p=q+1) {
	      for (; q<=n && !getSquare(suf[i], p, j, q, k, n); q++);
	      ans = max(ans, (q-p)*(k-j+1));
	    }
	  }
	}
      }

      for (int i=1; i<=m; i++) {
	for (int p=1, q=1; q<=n; q++) {
	  for (; p<=q && getLongest(n, s, suf, p, q, w)<i; p++);
	  ans = max(ans, (q-p+1)*i);
	}
      }
    }

    printf("%d\n", ans);
  }
  fclose(stdin);
  fclose(stdout);
  return 0;
}
